<!DOCTYPE html>

<html>
<head>
  <title>Docco</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <link rel="stylesheet" media="all" href="public/stylesheets/normalize.css" />
  <link rel="stylesheet" media="all" href="resources/linear/docco.css" />
</head>
<body>
  <div class="container">
    <div class="page">

      <div class="header">
        
          
          <h1 id="docco">Docco</h1>

          
        

        
      </div>

      
        
        <p><strong>Docco</strong> is a quick-and-dirty documentation generator, written in
<a href="http://coffeescript.org/#literate">Literate CoffeeScript</a>.
It produces an HTML document that displays your comments intermingled with your
code. All prose is passed through
<a href="http://daringfireball.net/projects/markdown/syntax">Markdown</a>, and code is
passed through <a href="http://highlightjs.org/">Highlight.js</a> syntax highlighting.
This page is the result of running Docco against its own
<a href="https://github.com/jashkenas/docco/blob/master/docco.litcoffee">source file</a>.</p>
<ol>
<li><p>Install Docco with <strong>npm</strong>: <code>sudo npm install -g docco</code></p>
</li>
<li><p>Run it against your code: <code>docco src/*.coffee</code></p>
</li>
</ol>
<p>There is no “Step 3”. This will generate an HTML page for each of the named
source files, with a menu linking to the other pages, saving the whole mess
into a <code>docs</code> folder (configurable).</p>
<p>The <a href="http://github.com/jashkenas/docco">Docco source</a> is available on GitHub,
and is released under the <a href="http://lillicense.org/v1.html">Lil License</a>.</p>
<p>Docco can be used to process code written in any programming language. If it
doesn’t handle your favorite yet, feel free to
<a href="https://github.com/jashkenas/docco/blob/master/resources/languages.json">add it to the list</a>.
Finally, the <a href="http://coffeescript.org/#literate">“literate” style</a> of <em>any</em>
language listed in <a href="https://github.com/jashkenas/docco/blob/master/resources/languages.json">languages.json</a>
is also supported — just tack an <code>.md</code> extension on the end:
<code>.coffee.md</code>, <code>.py.md</code>, and so on.</p>
<h2 id="partners-in-crime">Partners in Crime:</h2>

        
      
        
        <ul>
<li><p>If Node.js doesn’t run on your platform, or you’d prefer a more
convenient package, get <a href="http://github.com/rtomayko">Ryan Tomayko</a>‘s
<a href="http://rtomayko.github.io/rocco/rocco.html">Rocco</a>, the <strong>Ruby</strong> port that’s
available as a gem.</p>
</li>
<li><p>If you’re writing shell scripts, try
<a href="http://rtomayko.github.io/shocco/">Shocco</a>, a port for the <strong>POSIX shell</strong>,
also by Mr. Tomayko.</p>
</li>
<li><p>If <strong>Python</strong> is more your speed, take a look at
<a href="http://github.com/fitzgen">Nick Fitzgerald</a>‘s <a href="https://pycco-docs.github.io/pycco/">Pycco</a>.</p>
</li>
<li><p>For <strong>Clojure</strong> fans, <a href="http://blog.fogus.me/">Fogus</a>‘s
<a href="http://fogus.me/fun/marginalia/">Marginalia</a> is a bit of a departure from
“quick-and-dirty”, but it’ll get the job done.</p>
</li>
<li><p>There’s a <strong>Go</strong> port called <a href="http://nikhilm.github.io/gocco/">Gocco</a>,
written by <a href="https://github.com/nikhilm">Nikhil Marathe</a>.</p>
</li>
<li><p>For all you <strong>PHP</strong> buffs out there, Fredi Bach’s
<a href="http://jquery-jkit.com/sourcemakeup/">sourceMakeup</a> (we’ll let the faux pas
with respect to our naming scheme slide), should do the trick nicely.</p>
</li>
<li><p><strong>Lua</strong> enthusiasts can get their fix with
<a href="https://github.com/rgieseke">Robert Gieseke</a>‘s <a href="http://rgieseke.github.io/locco/">Locco</a>.</p>
</li>
<li><p>And if you happen to be a <strong>.NET</strong>
aficionado, check out <a href="https://github.com/dontangg">Don Wilson</a>‘s
<a href="http://dontangg.github.io/nocco/">Nocco</a>.</p>
</li>
<li><p>Going further afield from the quick-and-dirty, <a href="http://nevir.github.io/groc/">Groc</a>
is a <strong>CoffeeScript</strong> fork of Docco that adds a searchable table of contents,
and aims to gracefully handle large projects with complex hierarchies of code.</p>
</li>
<li><p>For <strong>ES6</strong> fans, <a href="https://github.com/mobily-enterprises/docco-next">Docco Next</a>
is an expanded rewrite of Docco in modern JavaScript, thoroughly commented,
and with the bonus that your existing templates will still work.</p>
</li>
</ul>
<p>Note that not all ports support all Docco features.</p>
<h2 id="main-documentation-generation-functions">Main Documentation Generation Functions</h2>

        
      
        
        <p>Generate the documentation for our configured source file by copying over static
assets, reading all the source files in, splitting them up into prose+code
sections, highlighting each file in the appropriate language, and printing them
out in an HTML template.</p>

        
          <div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">document</span> = <span class="hljs-params">(options = {}, callback)</span> -&gt;</span>
  config = configure options

  fs.mkdirs config.output, <span class="hljs-function">-&gt;</span>

    callback <span class="hljs-keyword">or</span>= <span class="hljs-function"><span class="hljs-params">(error)</span> -&gt;</span> <span class="hljs-keyword">throw</span> error <span class="hljs-keyword">if</span> error
<span class="hljs-function">    <span class="hljs-title">copyAsset</span>  = <span class="hljs-params">(file, callback)</span> -&gt;</span>
      <span class="hljs-keyword">return</span> callback() <span class="hljs-keyword">unless</span> fs.existsSync file
      fs.copy file, path.join(config.output, path.basename(file)), callback
<span class="hljs-function">    <span class="hljs-title">complete</span>   = -&gt;</span>
      copyAsset config.css, <span class="hljs-function"><span class="hljs-params">(error)</span> -&gt;</span>
        <span class="hljs-keyword">return</span> callback error <span class="hljs-keyword">if</span> error
        <span class="hljs-keyword">return</span> copyAsset config.public, callback <span class="hljs-keyword">if</span> fs.existsSync config.public
        callback()

    files = config.sources.slice()
<span class="hljs-function">
    <span class="hljs-title">nextFile</span> = -&gt;</span>
      source = files.shift()
      fs.readFile source, <span class="hljs-function"><span class="hljs-params">(error, buffer)</span> -&gt;</span>
        <span class="hljs-keyword">return</span> callback error <span class="hljs-keyword">if</span> error

        code = buffer.toString()
        sections = parse source, code, config
        format source, sections, config
        write source, sections, config
        <span class="hljs-keyword">if</span> files.length <span class="hljs-keyword">then</span> nextFile() <span class="hljs-keyword">else</span> complete()

    nextFile()</pre></div>
        
      
        
        <p>Given a string of source code, <strong>parse</strong> out each block of prose and the code that
follows it — by detecting which is which, line by line — and then create an
individual <strong>section</strong> for it. Each section is an object with <code>docsText</code> and
<code>codeText</code> properties, and eventually <code>docsHtml</code> and <code>codeHtml</code> as well.</p>

        
          <div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">parse</span> = <span class="hljs-params">(source, code, config = {})</span> -&gt;</span>
  lines    = code.split <span class="hljs-string">&#x27;\n&#x27;</span>
  sections = []
  lang     = getLanguage source, config
  hasCode  = docsText = codeText = <span class="hljs-string">&#x27;&#x27;</span>
<span class="hljs-function">
  <span class="hljs-title">save</span> = -&gt;</span>
    sections.push {docsText, codeText}
    hasCode = docsText = codeText = <span class="hljs-string">&#x27;&#x27;</span></pre></div>
        
      
        
        <p>Our quick-and-dirty implementation of the literate programming style. Simply
invert the prose and code relationship on a per-line basis, and then continue as
normal below.</p>

        
          <div class='highlight'><pre>  <span class="hljs-keyword">if</span> lang.literate
    isText = maybeCode = <span class="hljs-literal">yes</span>
    <span class="hljs-keyword">for</span> line, i <span class="hljs-keyword">in</span> lines
      lines[i] = <span class="hljs-keyword">if</span> maybeCode <span class="hljs-keyword">and</span> match = <span class="hljs-regexp">/^([ ]{4}|[ ]{0,3}\t)/</span>.exec line
        isText = <span class="hljs-literal">no</span>
        line[match[<span class="hljs-number">0</span>].length..]
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> maybeCode = <span class="hljs-regexp">/^\s*$/</span>.test line
        <span class="hljs-keyword">if</span> isText <span class="hljs-keyword">then</span> lang.symbol <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>
      <span class="hljs-keyword">else</span>
        isText = <span class="hljs-literal">yes</span>
        lang.symbol + <span class="hljs-string">&#x27; &#x27;</span> + line

  <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> lines
    <span class="hljs-keyword">if</span> line.match(lang.commentMatcher) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> line.match(lang.commentFilter)
      save() <span class="hljs-keyword">if</span> hasCode
      docsText += (line = line.replace(lang.commentMatcher, <span class="hljs-string">&#x27;&#x27;</span>)) + <span class="hljs-string">&#x27;\n&#x27;</span>
      save() <span class="hljs-keyword">if</span> <span class="hljs-regexp">/^(---+|===+)$/</span>.test line
    <span class="hljs-keyword">else</span>
      hasCode = <span class="hljs-literal">yes</span>
      codeText += line + <span class="hljs-string">&#x27;\n&#x27;</span>
  save()

  sections</pre></div>
        
      
        
        <p>To <strong>format</strong> and highlight the now-parsed sections of code, we use <strong>Highlight.js</strong>
over stdio, and run the text of their corresponding comments through
<strong>Markdown</strong>, using <a href="https://github.com/chjj/marked">Marked</a>.</p>

        
          <div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">format</span> = <span class="hljs-params">(source, sections, config)</span> -&gt;</span>
  language = getLanguage source, config</pre></div>
        
      
        
        <p>Pass any user defined options to Marked if specified via command line option</p>

        
          <div class='highlight'><pre>  markedOptions =
    smartypants: <span class="hljs-literal">true</span>

  <span class="hljs-keyword">if</span> config.marked
    markedOptions = config.marked

  marked.setOptions markedOptions</pre></div>
        
      
        
        <p>Tell Marked how to highlight code blocks within comments, treating that code
as either the language specified in the code block or the language of the file
if not specified.</p>

        
          <div class='highlight'><pre>  marked.setOptions {
    highlight: <span class="hljs-function"><span class="hljs-params">(code, lang)</span> -&gt;</span>
      lang <span class="hljs-keyword">or</span>= language.name

      <span class="hljs-keyword">if</span> highlightjs.getLanguage(lang)
        highlightjs.highlight(code, {language: lang}).value
      <span class="hljs-keyword">else</span>
        console.warn <span class="hljs-string">&quot;docco: couldn&#x27;t highlight code block with unknown language &#x27;<span class="hljs-subst">#{lang}</span>&#x27; in <span class="hljs-subst">#{source}</span>&quot;</span>
        code
  }

  <span class="hljs-keyword">for</span> section, i <span class="hljs-keyword">in</span> sections
    code = highlightjs.highlight(section.codeText, {language: language.name}).value
    code = code.replace(<span class="hljs-regexp">/\s+$/</span>, <span class="hljs-string">&#x27;&#x27;</span>)
    section.codeHtml = <span class="hljs-string">&quot;&lt;div class=&#x27;highlight&#x27;&gt;&lt;pre&gt;<span class="hljs-subst">#{code}</span>&lt;/pre&gt;&lt;/div&gt;&quot;</span>
    section.docsHtml = marked(section.docsText)</pre></div>
        
      
        
        <p>Once all of the code has finished highlighting, we can <strong>write</strong> the resulting
documentation file by passing the completed HTML sections into the template,
and rendering it to the specified output path.</p>

        
          <div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">write</span> = <span class="hljs-params">(source, sections, config)</span> -&gt;</span>
<span class="hljs-function">
  <span class="hljs-title">destination</span> = <span class="hljs-params">(file)</span> -&gt;</span>
    path.join(config.output, path.dirname(file), path.basename(file, path.extname(file)) + <span class="hljs-string">&#x27;.html&#x27;</span>)
<span class="hljs-function">
  <span class="hljs-title">relative</span> = <span class="hljs-params">(file)</span> -&gt;</span>
    to = path.dirname(path.resolve(file))
    <span class="hljs-keyword">from</span> = path.dirname(path.resolve(destination(source)))
    path.join(path.relative(<span class="hljs-keyword">from</span>, to), path.basename(file))</pre></div>
        
      
        
        <p>The <strong>title</strong> of the file is either the first heading in the prose, or the
name of the source file.</p>

        
          <div class='highlight'><pre>  firstSection = _.find sections, <span class="hljs-function"><span class="hljs-params">(section)</span> -&gt;</span>
    section.docsText.length &gt; <span class="hljs-number">0</span>
  first = marked.lexer(firstSection.docsText)[<span class="hljs-number">0</span>] <span class="hljs-keyword">if</span> firstSection
  hasTitle = first <span class="hljs-keyword">and</span> first.type <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;heading&#x27;</span> <span class="hljs-keyword">and</span> first.depth <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>
  title = <span class="hljs-keyword">if</span> hasTitle <span class="hljs-keyword">then</span> first.text <span class="hljs-keyword">else</span> path.basename source
  css = relative path.join(config.output, path.basename(config.css))

  html = config.template {sources: config.sources, css,
    title, hasTitle, sections, path, destination, relative}

  console.log <span class="hljs-string">&quot;docco: <span class="hljs-subst">#{source}</span> -&gt; <span class="hljs-subst">#{destination source}</span>&quot;</span>
  fs.outputFileSync destination(source), html</pre></div>
        
      
        
        <h2 id="configuration">Configuration</h2>

        
      
        
        <p>Default configuration <strong>options</strong>. All of these may be extended by
user-specified options.</p>

        
          <div class='highlight'><pre>defaults =
  layout:     <span class="hljs-string">&#x27;parallel&#x27;</span>
  output:     <span class="hljs-string">&#x27;docs&#x27;</span>
  template:   <span class="hljs-literal">null</span>
  css:        <span class="hljs-literal">null</span>
  extension:  <span class="hljs-literal">null</span>
  languages:  {}
  marked:     <span class="hljs-literal">null</span></pre></div>
        
      
        
        <p><strong>Configure</strong> this particular run of Docco. We might use a passed-in external
template, or one of the built-in <strong>layouts</strong>. We only attempt to process
source files for languages for which we have definitions.</p>

        
          <div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">configure</span> = <span class="hljs-params">(options)</span> -&gt;</span>
  config = _.extend {}, defaults, _.pick(options.opts(), _.keys(defaults)...)

  config.languages = buildMatchers config.languages</pre></div>
        
      
        
        <p>The user is able to override the layout file used with the <code>--template</code> parameter.
In this case, it is also neccessary to explicitly specify a stylesheet file.
These custom templates are compiled exactly like the predefined ones, but the <code>public</code> folder
is only copied for the latter.</p>

        
          <div class='highlight'><pre>  <span class="hljs-keyword">if</span> options.template
    <span class="hljs-keyword">unless</span> options.css
      console.warn <span class="hljs-string">&quot;docco: no stylesheet file specified&quot;</span>
    config.layout = <span class="hljs-literal">null</span>
  <span class="hljs-keyword">else</span>
    dir = config.layout = path.join __dirname, <span class="hljs-string">&#x27;resources&#x27;</span>, config.layout
    config.public       = path.join dir, <span class="hljs-string">&#x27;public&#x27;</span> <span class="hljs-keyword">if</span> fs.existsSync path.join dir, <span class="hljs-string">&#x27;public&#x27;</span>
    config.template     = path.join dir, <span class="hljs-string">&#x27;docco.jst&#x27;</span>
    config.css          = options.css <span class="hljs-keyword">or</span> path.join dir, <span class="hljs-string">&#x27;resources/linear/docco.css&#x27;</span>
  config.template = _.template fs.readFileSync(config.template).toString()

  <span class="hljs-keyword">if</span> options.marked
    config.marked = <span class="hljs-built_in">JSON</span>.parse fs.readFileSync(options.marked)

  config.sources = options.args.filter(<span class="hljs-function"><span class="hljs-params">(source)</span> -&gt;</span>
    lang = getLanguage source, config
    console.warn <span class="hljs-string">&quot;docco: skipped unknown type (<span class="hljs-subst">#{path.basename source}</span>)&quot;</span> <span class="hljs-keyword">unless</span> lang
    lang
  ).sort()

  config</pre></div>
        
      
        
        <h2 id="helpers--initial-setup">Helpers &amp; Initial Setup</h2>

        
      
        
        <p>Require our external dependencies.</p>

        
          <div class='highlight'><pre>_           = <span class="hljs-built_in">require</span> <span class="hljs-string">&#x27;underscore&#x27;</span>
fs          = <span class="hljs-built_in">require</span> <span class="hljs-string">&#x27;fs-extra&#x27;</span>
path        = <span class="hljs-built_in">require</span> <span class="hljs-string">&#x27;path&#x27;</span>
marked      = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;marked&#x27;</span>).marked
commander   = <span class="hljs-built_in">require</span> <span class="hljs-string">&#x27;commander&#x27;</span>
highlightjs = <span class="hljs-built_in">require</span> <span class="hljs-string">&#x27;highlight.js&#x27;</span></pre></div>
        
      
        
        <p>Languages are stored in JSON in the file <code>resources/languages.json</code>.
Each item maps the file extension to the name of the language and the
<code>symbol</code> that indicates a line comment. To add support for a new programming
language to Docco, just add it to the file.</p>

        
          <div class='highlight'><pre>languages = <span class="hljs-built_in">JSON</span>.parse fs.readFileSync(path.join(__dirname, <span class="hljs-string">&#x27;resources&#x27;</span>, <span class="hljs-string">&#x27;languages.json&#x27;</span>))</pre></div>
        
      
        
        <p>Build out the appropriate matchers and delimiters for each language.</p>

        
          <div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildMatchers</span> = <span class="hljs-params">(languages)</span> -&gt;</span>
  <span class="hljs-keyword">for</span> ext, l <span class="hljs-keyword">of</span> languages</pre></div>
        
      
        
        <p>Does the line begin with a comment?</p>

        
          <div class='highlight'><pre>    l.commentMatcher = <span class="hljs-regexp">///^\s*<span class="hljs-subst">#{l.symbol}</span>\s?///</span></pre></div>
        
      
        
        <p>Ignore <a href="http://en.wikipedia.org/wiki/Shebang_%28Unix%29">hashbangs</a> and interpolations…</p>

        
          <div class='highlight'><pre>    l.commentFilter = <span class="hljs-regexp">/(^#![/</span>]|^\s*<span class="hljs-comment">#\{)/</span>
  languages
languages = buildMatchers languages</pre></div>
        
      
        
        <p>A function to get the current language we’re documenting, based on the
file extension. Detect and tag “literate” <code>.ext.md</code> variants.</p>

        
          <div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">getLanguage</span> = <span class="hljs-params">(source, config)</span> -&gt;</span>
  ext  = config.extension <span class="hljs-keyword">or</span> path.extname(source) <span class="hljs-keyword">or</span> path.basename(source)
  lang = config.languages?[ext] <span class="hljs-keyword">or</span> languages[ext]
  <span class="hljs-keyword">if</span> lang <span class="hljs-keyword">and</span> lang.name <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;markdown&#x27;</span>
    codeExt = path.extname(path.basename(source, ext))
    codeLang = config.languages?[codeExt] <span class="hljs-keyword">or</span> languages[codeExt]
    <span class="hljs-keyword">if</span> codeExt <span class="hljs-keyword">and</span> codeLang
      lang = _.extend {}, codeLang, {literate: <span class="hljs-literal">yes</span>}
  lang</pre></div>
        
      
        
        <p>Keep it DRY. Extract the docco <strong>version</strong> from <code>package.json</code></p>

        
          <div class='highlight'><pre>version = <span class="hljs-built_in">JSON</span>.parse(fs.readFileSync(path.join(__dirname, <span class="hljs-string">&#x27;package.json&#x27;</span>))).version</pre></div>
        
      
        
        <h2 id="command-line-interface">Command Line Interface</h2>

        
      
        
        <p>Finally, let’s define the interface to run Docco from the command line.
Parse options using <a href="https://github.com/visionmedia/commander.js">Commander</a>.</p>

        
          <div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">run</span> = <span class="hljs-params">(args = process.argv)</span> -&gt;</span>
  c = defaults
  commander.version(version)
    .usage(<span class="hljs-string">&#x27;[options] files&#x27;</span>)
    .option(<span class="hljs-string">&#x27;-L, --languages [file]&#x27;</span>, <span class="hljs-string">&#x27;use a custom languages.json&#x27;</span>, _.compose <span class="hljs-built_in">JSON</span>.parse, fs.readFileSync)
    .option(<span class="hljs-string">&#x27;-l, --layout [name]&#x27;</span>,    <span class="hljs-string">&#x27;choose a layout (parallel, linear or classic)&#x27;</span>, c.layout)
    .option(<span class="hljs-string">&#x27;-o, --output [path]&#x27;</span>,    <span class="hljs-string">&#x27;output to a given folder&#x27;</span>, c.output)
    .option(<span class="hljs-string">&#x27;-c, --css [file]&#x27;</span>,       <span class="hljs-string">&#x27;use a custom css file&#x27;</span>, c.css)
    .option(<span class="hljs-string">&#x27;-t, --template [file]&#x27;</span>,  <span class="hljs-string">&#x27;use a custom .jst template&#x27;</span>, c.template)
    .option(<span class="hljs-string">&#x27;-e, --extension [ext]&#x27;</span>,  <span class="hljs-string">&#x27;assume a file extension for all inputs&#x27;</span>, c.extension)
    .option(<span class="hljs-string">&#x27;-m, --marked [file]&#x27;</span>,    <span class="hljs-string">&#x27;use custom marked options&#x27;</span>, c.marked)
    .parse(args)
    .name = <span class="hljs-string">&quot;docco&quot;</span>
  <span class="hljs-keyword">if</span> commander.args.length
    document commander
  <span class="hljs-keyword">else</span>
    console.log commander.helpInformation()</pre></div>
        
      
        
        <h2 id="public-api">Public API</h2>

        
      
        
        
        
          <div class='highlight'><pre>Docco = module.<span class="hljs-built_in">exports</span> = {run, document, parse, format, version}</pre></div>
        
      
      <div class="fleur">h</div>
    </div>
  </div>
</body>
</html>
